﻿#include "soundtouchex.h"

SoundTouchEx::SoundTouchEx()
{
    //默认音频参数
    sampleRate = 44100;
    channel = 2;
    bytePerSample = 2;

    //默认最大处理接收数
    maxRecv = 1024;

    buffer.initBuffer(MaxTouchBufferSize * 20);
}

SoundTouchEx::~SoundTouchEx()
{
}

void SoundTouchEx::setProcessParm(int sampleRate, int channel, int bytePerSample, double tempo, double pitch)
{
    this->sampleRate = sampleRate;
    this->channel = channel;
    this->bytePerSample = bytePerSample;

    soundTouch.setSampleRate(sampleRate); // 设置采样率
    soundTouch.setChannels(channel);      // 设置通道数
    soundTouch.setTempo(tempo);      //变速
    soundTouch.setPitch(pitch);      //变调
}

void SoundTouchEx::processAudioData(char *inPcmBuf, int inPcmBufSize)
{
    //计算此次数据中包含的sample个数
    int nSamples = inPcmBufSize / channel / bytePerSample;

    //将nSamples个数的样本写入soundTouch进行处理 注：需要数据缓冲，可能putSamples多次，才能receiveSamples收到处理后的音频数据
    soundTouch.putSamples((short*)inPcmBuf, nSamples);

    //循环接收处理后的音频数据 因为putSamples与receiveSamples的个数不对等，存在多次才接收完的情况
    while(1)
    {
        //返回处理好的样本个数 每次接收个数不会超过最大值maxRecv 防止一次接收的数据量过大
        nSamples = soundTouch.receiveSamples(touchBuffer, maxRecv);
        if(nSamples == 0)
            break;

        //根据样本数，计算处理后的数据长度
        int length = nSamples * channel * bytePerSample;

        //写入处理后的缓冲区
        buffer.writeBuffer((char *)touchBuffer, length);
    }
}

void SoundTouchEx::flushLastData()
{
    //存在剩余的处理好的数据，冲刷一下
    soundTouch.flush();
    while(1)
    {
        //接收处理后的数据，步骤与上相同
        int nSamples = soundTouch.receiveSamples(touchBuffer, maxRecv);
        if(nSamples == 0)
            break;

        int length = nSamples * channel * bytePerSample;

        //写入处理后的缓冲区
        buffer.writeBuffer((char *)touchBuffer, length);
    }
}

